package com.example.erp.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.util.ObjectUtil;
import com.example.erp.config.CommonConfig;
import com.example.erp.dto.loginDTO.CaptchaDTO;
import com.example.erp.dto.loginDTO.LoginDTO;
import com.example.erp.dto.loginDTO.UserInfoDTO;
import com.example.erp.dto.loginDTO.routerDTO.ChildDTO;
import com.example.erp.dto.loginDTO.routerDTO.MetaDTO;
import com.example.erp.dto.loginDTO.routerDTO.RouterDTO;
import com.example.erp.mapper.LoginMapper;
import com.example.erp.mapper.permission.RoleMapper;
import com.example.erp.mapper.permission.UserMapper;
import com.example.erp.mapper.permission.UserRoleMapper;
import com.example.erp.mapper.system.MenuMapper;
import com.example.erp.pojo.permission.Role;
import com.example.erp.pojo.permission.User;
import com.example.erp.pojo.system.Menu;
import com.example.erp.service.LoginService;
import com.example.erp.utils.DataFormatUtils;
import com.example.erp.utils.JwtUtils;
import com.example.erp.utils.RSAUtils;
import com.example.erp.utils.Result;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.awt.image.BufferedImage;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class LoginServiceA implements LoginService {
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private DefaultKaptcha defaultKaptcha;
    @Autowired
    private LoginMapper loginMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private MenuMapper menuMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;

    @Override
    public Result generateCaptcha(HttpServletRequest request) {
        // 1.获取四位验证码
        String capText = defaultKaptcha.createText();
        // 2.获取密令
        String uuid = UUID.randomUUID().toString();
        // 3.创建验证码图片
        BufferedImage bi = defaultKaptcha.createImage(capText);
        // 4.图片转为base64
        String img = ImgUtil.toBase64DataUri(bi, ImgUtil.IMAGE_TYPE_PNG);

        CaptchaDTO cap = new CaptchaDTO(uuid, img);
        request.getSession().setAttribute(uuid + capText.toUpperCase(), cap);
        return Result.success(cap);
    }

    @Override
    public Result login(LoginDTO loginDTO, HttpServletRequest request) {
        String key = loginDTO.getUuid() + loginDTO.getCaptchaKey().toUpperCase();
        Object cap = request.getSession().getAttribute(key);

        if (cap == null) {
            return Result.error(CommonConfig.resultMsg.LOGINCODE.getDescription());
        }
        if (loginMapper.loginUsername(loginDTO) == null) {
            return Result.error(CommonConfig.resultMsg.LOGINNAMEQUERY.getDescription());
        }
        String password = RSAUtils.decrypt(loginDTO.getPassword());
        User user = loginMapper.login(loginDTO);
        if (user == null) {
            return Result.error(CommonConfig.resultMsg.LOGINPWDQUERY.getDescription());
        }
        if (!passwordEncoder.matches(password, user.getPassword())) {
            return Result.error(CommonConfig.resultMsg.LOGINPWDQUERY.getDescription());
        }
        if (user.getStatus() != CommonConfig.compare.STATUSONE.getDescription()) {
            return Result.login(CommonConfig.resultMsg.USERSTATUSERROR.getDescription());
        }
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", user.getId());
        claims.put("username", user.getUsername());
        String jwt = JwtUtils.generateJwt(claims);

        return Result.success(jwt);
    }

    @Override
    public Result getRouters(String token) {
        Long userId = DataFormatUtils.getTokenUser(token, "id");
        List<Long> roles = userRoleMapper.getRoleIdByUserId(userId);
        if (CollUtil.isEmpty(roles)) {
            return Result.login(CommonConfig.resultMsg.ROLEERROR.getDescription());
        }
        List<Role> roleList = roleMapper.getByIds(roles);
        // 判断是否有管理员角色
        boolean hasAdminRole = roleList.stream()
                .anyMatch(role -> "admin".equals(role.getRoleKey()));
        List<Long> mergedMenuIds;
        if (hasAdminRole) {
            // 如果是管理员角色，这里预留空间给你写自己的代码
            // 例如：直接返回所有菜单
            mergedMenuIds = menuMapper.getAllRouters();
        } else {
            // 非管理员角色，获取角色对应的菜单
            mergedMenuIds = roleList.stream()
                    .map(role -> DataFormatUtils.getListOfStr(role.getMenuIdsStr(), Long.class))
                    .flatMap(List::stream)
                    .distinct()
                    .collect(Collectors.toList());
        }

        List<Menu> list = menuMapper.getRouters(mergedMenuIds);
        //菜单返回路由
        List<RouterDTO> routers = new ArrayList<>();
        Map<Long, List<ChildDTO>> childRen = new HashMap<>();

        //getAffix == 2 导航菜单栏是否不可删除 2=不可删除
        //getHidden == 2 导航菜单栏是否显示 2=隐藏
        //getNoCache == 2 页面组件是否缓存 2=缓存
        //getIsFrame == 1 页面组件是否外链 1=是 2=不是
        for (Menu menu : list) {
            MetaDTO metaDTO = new MetaDTO(menu.getMenuName(), menu.getIcon(), (menu.getAffix() == CommonConfig.compare.STATUSTWO.getDescription()), (menu.getNoCache() == CommonConfig.compare.STATUSTWO.getDescription()), (menu.getIsFrame() == CommonConfig.compare.STATUSONE.getDescription()), (menu.getBreadcrumb() == CommonConfig.compare.STATUSONE.getDescription()), menu.getActiveMenu());
            if (menu.getParentId() == null || menu.getParentId() == 0) {
                RouterDTO routerDTO = new RouterDTO(menu.getMenuId(), menu.getPath(), menu.getComponent(), (menu.getHidden() == CommonConfig.compare.STATUSTWO.getDescription()), menu.getRedirect(), menu.getName(), (menu.getAlwaysShow() == CommonConfig.compare.STATUSONE.getDescription()), metaDTO);
                routers.add(routerDTO);
            } else {
                List<ChildDTO> childDTOS = childRen.getOrDefault(menu.getParentId(), new ArrayList<>());
                ChildDTO childDTO = new ChildDTO(menu.getMenuId(), menu.getPath(), menu.getComponent(), menu.getName(), (menu.getHidden() == CommonConfig.compare.STATUSTWO.getDescription()), (menu.getAlwaysShow() == CommonConfig.compare.STATUSONE.getDescription()), metaDTO);
                childDTOS.add(childDTO);
                childRen.put(menu.getParentId(), childDTOS);
            }
        }
        for (RouterDTO routerDTO : routers) {
            routerDTO.setChildren(childRen.getOrDefault(routerDTO.getMenuId(), new ArrayList<>()));
        }
        return Result.success(routers);
    }

    @Override
    public Result getInfo(String token) {
        //解析token的id
        Long userId = DataFormatUtils.getTokenUser(token, "id");
        List<Long> roles = userRoleMapper.getRoleIdByUserId(userId);
        if (CollUtil.isEmpty(roles)) {
            return Result.login(CommonConfig.resultMsg.ROLEERROR.getDescription());
        }
        List<String> rolesKey = roleMapper.getKeyById(roles);
        List<String> roleNames = roleMapper.getNameById(roles);
        User user = userMapper.getById(userId);
        if (ObjectUtil.isNotNull(user)) {
            user.setImageList(DataFormatUtils.getListOfStr(user.getAvatar(), String.class));
            user.setRoleIds(roles);
            user.setRoleNames(roleNames);
        }
        List<Role> roleList = roleMapper.getByIds(roles);
        boolean hasAdminRole = roleList.stream()
                .anyMatch(role -> "admin".equals(role.getRoleKey()));
        List<Long> mergedMenuIds;
        if (hasAdminRole) {
            // 如果是管理员角色，这里预留空间给你写自己的代码
            // 例如：直接返回所有菜单
            mergedMenuIds = menuMapper.getAllRouters();
        } else {
            // 非管理员角色，获取角色对应的菜单
            mergedMenuIds = roleList.stream()
                    .map(role -> DataFormatUtils.getListOfStr(role.getMenuIdsStr(), Long.class))
                    .flatMap(List::stream)
                    .distinct()
                    .collect(Collectors.toList());
        }
        List<Menu> list = menuMapper.getPermissions(mergedMenuIds);
        //集合菜单和权限
        Map<Long, Menu> menuMap = new HashMap<>();
        List<String> permissions = new ArrayList<>();
        for (Menu menu : list) {
            menuMap.put(menu.getMenuId(), menu);
        }
        for (Menu button : list) {
            if (button.getMenuType().equals(CommonConfig.menuType.F.name())) {
                Menu parent = menuMap.getOrDefault(button.getParentId(), null);
                Menu directory = menuMap.getOrDefault(parent.getParentId(), null);
                if (directory != null) {
                    permissions.add(directory.getName() + ":" + parent.getName() + ":" + button.getName());
                }
            }
        }

        UserInfoDTO userInfoDTO = new UserInfoDTO(user, permissions, rolesKey);
        return Result.success(userInfoDTO);
    }
}
